import { Processor, WorkerHost } from "@nestjs/bullmq";
import { Logger } from "@nestjs/common";
import { InjectDataSource } from "@nestjs/typeorm";
import { Job } from "bullmq";
import dayjs from "dayjs";
import { DataSource } from "typeorm";
import { SysLogClassMap } from "@/common/interceptors/create-log.interceptor";
import { DatabaseName } from "@/database/database.enum";
import { EntitySysLogDto } from "../dto/entity-sys-log.dto";

interface JobData {
    requestId: string;
    entityName: string | null;
    logData: EntitySysLogDto;
}

@Processor("sysLogQueue") // 对应队列名
export class SysLogCreateProcessor extends WorkerHost {
    private readonly logger = new Logger(SysLogCreateProcessor.name);

    constructor(
        @InjectDataSource(DatabaseName.LOGS)
        private readonly logsDataSource: DataSource,
        @InjectDataSource() // 默认数据源,用于查询业务实体
        private readonly defaultDataSource: DataSource,
    ) {
        super();
    }

    /** 处理创建日志的任务 */
    async process(job: Job<JobData, any, string>) {
        try {
            const { requestId, entityName, logData } = job.data;

            const entity = entityName ? SysLogClassMap.get(entityName) : null;

            if (["update", "delete"].includes(logData.type) && entity && requestId) {
                // 在删除或更新之前读取旧数据
                const oldData = await this.defaultDataSource.getRepository(entity).findOneBy({ id: requestId });
                logData.oldData = oldData ? JSON.stringify(oldData) : null;
            }

            // 获取当前月份，确定目标表名
            const currentMonth = dayjs().format("YYYYMM");
            const tableName = `sys_operation_log_${currentMonth}`;

            // 使用原生 SQL 插入数据到分表
            await this.logsDataSource.query(
                `INSERT INTO ${tableName} (
                id, module, type, action, operator_id, request_url,
                request_method, request_data, response_data, old_data,
                ip_address, user_agent, created_at
            ) VALUES (
                $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13
            )`,
                [
                    logData.id,
                    logData.module,
                    logData.type,
                    logData.action,
                    logData.operatorId || null,
                    logData.requestUrl || null,
                    logData.requestMethod || null,
                    logData.requestData ? JSON.parse(logData.requestData) : null,
                    logData.responseData ? JSON.parse(logData.responseData) : null,
                    logData.oldData ? JSON.parse(logData.oldData) : null,
                    logData.ipAddress || null,
                    logData.userAgent || null,
                    logData.createdAt ? dayjs(logData.createdAt).toDate() : null,
                ],
            );
        } catch (error) {
            this.logger.error("Error processing sysLog job:", error);
            return;
        }
    }
}
